Okay.
In this lecture we're going to take a look at creating a basic admin system.
This admin system features an on screen command line that you can bring up, pressing the semicolon
button, and you can enter in any commands you'd like in here.
And we're also going to add chat support for commands as well.
So I can use a command such as speed me and set a number like 100.
And then I increase my speed and then I can do some other wacky commands like killing myself.
So kill me and it kills the character.
And of course we can do the exact same commands in the command line as well.
If we hit a colon, we can see all of the commands that are available to us, and we can fill out any
of these things, such as flinging ourselves so we can do fling me and it'll fling us far away.
Our admin system also features an on screen messaging system to let the user know whoever is using commands,
whether or not they made a mistake.
So, for example, if I wanted to set my speed and I don't enter in a number, let's say I enter in
a random string like that, it's going to give me an error and it's going to tell me command speed expected
number for argument number two got string instead, and we can hit okay.
And now we'll know to fix our command.
To get started, I've attached a model to the lecture you're going to want to grab and insert into your
game.
Inside of this model, we have a couple things we need to put in some services we have a folder of all
the assets we'll need for our admin system, including some bind tables, a bindable function, a remote
function, as well as a remote event, as well as some other module scripts to store the commands for
our admin, storing some of the settings for the admin and one module script to act as an enum for our
admin system.
So you can go ahead and take first the server script to handle our admin system and put that inside
of server script service.
And we can go ahead and take this folder and place it inside of replicated storage.
And in here we can go ahead and take a look at some of the module scripts.
So for admin enum we just have a couple key value pairs in here to represent different values for administrators.
So anybody who's a non admin will have a rank of zero.
Moderators have a rank of ten admin a rank of 20 and owners 250.
So these numbers just represent, you know, different levels to set for commands.
And then of course we also have a module script to store some settings such as what prefix we want to
use for the command.
So we could change it from a colon to an exclamation mark.
We could do a semicolon, but I'll just do a colon for now.
And then in here we can store all of the hard coded players we want to have admin in our game.
So for example here this is my players ID.
And I've hard coded it to set myself to be the owner for this admin system.
And then we have a couple other tables to keep track of temporary mods or server mods and server bans.
So if we want to ban anybody we'll storm in here.
And kick them if they're in this table.
One more thing we want to set up.
We want to go into our command module script.
And in here we're going to store a table that contains all of the commands.
And we can actually set this up real quick.
So I want to just have two services in here.
One is going to be the run service.
And then we're just going to, of course, need replicated storage.
And then from this point I want to create a boolean I'll call it is server.
And we're going to use the run service to check whether or not this module script is running on the
client or on the server.
And that's because I'm going to have this module script required by both the client and the server.
That way the client can see what commands they have access to, and that way the server can require
it as well and execute all of the server functionality for different commands.
So if we're on the server, then I just want to create some variables specific to the server.
So one I'll call coms Bindable.
And I'm not going to make it local here because I want it to be available to the entire script.
If I made it local, it would be confined to this if statement.
So I don't want to do that.
So we're going to get inside of replicated storage, our admin assets and get our communication bindable.
And this is for communication between different server scripts.
We're going to have one Coms event.
And this is going to be for communication between the client and the server.
And then we're going to require the admin settings module script.
So replicated storage admin assets and get the settings module script.
And we're going to go ahead and require this.
Otherwise.
I also want to require the admin enum, and we can do this on both the client and the server.
So require script dot parent.
And we could just do admin enum.
This shouldn't be an issue for the client, but if you'd like you could go ahead and use wait for child,
but I don't think it's necessary.
And then I'm going to use RNG.
So we're going to create a new random data type.
And we're going to use that later for different commands.
Now inside of here, I just want to have one private function and that's for checking arguments passed
to functions checking their type.
So again we'll do check arg.
For type.
We will take an argument and we want to check the type.
So we'll call it expected type and set it to a string.
Now when this function gets called of course we first want to make sure that we didn't pass nil to the
second parameter so we could assert.
Expected type.
If it's nil or false, then we're going to send a message like check arg or type requires string for
expected type.
But we got no we could just say got no.
Another thing we want to check is if the type of expected type is not equal to a string, because we
want a string here.
But if for some reason whoever is scripting in here didn't pass a string, we want to let them know
so we can error and we could say something like check arg for type requires string for expected type
and we got whatever instead.
So we're going to put a directive in here.
And then we're going to use the format function.
And what do we want to replace at that directive.
Well we can get the string of the type expected type.
So it could be like a number a boolean whatever.
They didn't pass a string.
So we're going to error and let them know.
Otherwise we're going to use some syntax magic here.
And I'm going to put a return statement.
And inside this return statement I'm going to put an if statement.
So if the type of our argument is equal to the expected type, or let's say the type of our argument
is an instance.
So we want to check the class of this instance.
So and arg is a and we'll pass the expected type here.
So if it's either the expected type or it's an instance and belongs to the class we expect, then we're
going to put true here.
So that means if this if statement evaluates to true it's going to return true.
Otherwise we can put else and then just put false here.
So what this is doing is it's evaluating whether or not this is going to be true or false.
If the condition is true and the if statement, it's going to return true, otherwise it's going to
return false.
And guess what.
We don't have to put an end statement here.
So that's a little bit of some syntactical magic here in Lua.
Now let's go ahead and go into our current commands table, because in here I want to create some or
I'll just create an example key value pair.
So we'll put a key here as a string and we'll just do example.
So this will be our example command.
And what I want to store in this command is first I want to give a name to our command.
So what's the name of our command?
I'm just going to put example here for now.
The next thing we want is we want to define the minimum rank for this command.
So what players or what administrators in our game can use this command.
So we could do minimum.
Minimum rank is equal to and we can use our admin enum.
So admin enum.
And for now we could just set it to like moderator.
Uh, we can define the usage for this command.
So for example, maybe a player could type like colon kill or they could also do like colon.
Uh, oops.
Death.
You know, we want to give them multiple options for this command.
So for now I'll just do example and then example two.
And we don't need to put the colon in here.
We'll add that in later because I want to be able to change the prefix only from the script alone.
And I don't want it to have to go into each command and change each semicolon by itself.
That'd be a little redundant.
The next thing we need to define is the required parameters for this command.
So as you know, different commands are going to have different parameters.
Some will require a player, some will require a number or multiple different parameters.
So we'll have a table that stores all of the parameters for this command in order.
And we'll declare the type of those parameters here.
So for example, maybe the first parameter needs to be of the type player.
And maybe the second parameter needs to be of the type number.
And then the last thing we'll need inside of this function I'm going to call it callback.
And that means we're going to be calling back a function.
So there's going to be a function stored here.
And this function is going to execute all of the functionality for this command.
And in here this is where you would define the parameters.
So like clam one would be our player and param two would be our number.
And then when we would execute according to those parameters and whatever the command is.
And then at the very end, uh, to make sure that everything went smoothly, we can return true.
Otherwise, if something goes wrong in this function, we could return false and give them an error
message like something wrong happened or something like that.
And we can make sure to denote that using type annotation.
So we could say that this returns a boolean.
And it could also possibly return a string.
So we'll put a question mark there, because if it returns true then it's not going to return a string.
Alrighty.
So now that we've got everything set up in the next lecture, we're going to go ahead and start scripting
on the server.
So I'll go ahead and see you there.